commonlibsse_ng\re\n/
NiAVObject.rs

1use crate::re::NiBound::NiBound;
2use crate::re::NiCollisionObject::NiCollisionObject;
3use crate::re::NiObjectNET::NiObjectNET;
4use crate::re::NiSmartPointer::NiPointer;
5use crate::re::NiTransform::NiTransform;
6use crate::re::offsets_ni_rtti::NiRTTI_NiObject;
7use crate::re::offsets_rtti::RTTI_NiObject;
8use crate::re::offsets_vtable::VTABLE_NiObject;
9use crate::re::{NiNode, bhkCollisionObject};
10use crate::rel::id::VariantID;
11use crate::rel::relocation::{RelocationError, relocate_member, relocate_member_mut};
12use core::ffi::{c_float, c_void};
13
14#[repr(u32)]
15#[derive(Debug, Clone, Copy)]
16pub enum NiUpdateData_Flag {
17    None = 0,
18    Dirty = 1 << 0,
19    DisableCollision = 1 << 13,
20}
21
22#[repr(C)]
23#[derive(Debug)]
24pub struct NiUpdateData {
25    pub time: c_float,            // 0x00
26    pub flags: NiUpdateData_Flag, // 0x04
27}
28
29#[repr(C)]
30pub struct PerformOpFuncVtbl {
31    /// C++ class Destructor equivalent
32    pub CxxDrop: unsafe extern "C" fn(this: *mut c_void), // 00
33    /// C++ operator()
34    pub CxxOperatorCall: unsafe extern "C" fn(*mut c_void, *mut NiAVObject) -> bool, // 01
35}
36
37#[repr(C)]
38pub struct PerformOpFunc {
39    pub vtable: *const PerformOpFuncVtbl, // VTable pointer
40}
41
42#[repr(C)]
43#[derive(Debug)]
44pub struct NiAVObject {
45    pub __base: NiObjectNET,
46    pub parent: *mut NiNode,                            // 0x030
47    pub parent_index: u32,                              // 0x038
48    pub unk03C: u32,                                    // 0x03C
49    pub collision_object: NiPointer<NiCollisionObject>, // 0x040
50    pub local_transform: NiTransform,                   // 0x048
51    pub world_transform: NiTransform,                   // 0x07C
52    pub previous_world_transform: NiTransform,          // 0x0B0
53    pub world_bound: NiBound,                           // 0x0E4
54    pub unk_f4: u32,                                    // 0x0F4
55    pub unk_f8: u64,                                    // 0x0F8
56    pub fade_amount: c_float,                           // 0x100
57    pub last_updated_frame_counter: u32,                // 0x104
58    pub unk104: u64,                                    // 0x108
59}
60
61const _: () = {
62    assert!(core::mem::offset_of!(NiAVObject, __base) == 0x0);
63    assert!(core::mem::offset_of!(NiAVObject, parent) == 0x30);
64    assert!(core::mem::offset_of!(NiAVObject, parent_index) == 0x38);
65    assert!(core::mem::offset_of!(NiAVObject, unk03C) == 0x3C);
66    assert!(core::mem::offset_of!(NiAVObject, collision_object) == 0x40);
67    assert!(core::mem::offset_of!(NiAVObject, local_transform) == 0x48);
68    assert!(core::mem::offset_of!(NiAVObject, world_transform) == 0x7C);
69    assert!(core::mem::offset_of!(NiAVObject, previous_world_transform) == 0xB0);
70    assert!(core::mem::offset_of!(NiAVObject, world_bound) == 0xE4);
71    assert!(core::mem::offset_of!(NiAVObject, unk_f4) == 0xF4);
72    assert!(core::mem::offset_of!(NiAVObject, unk_f8) == 0xF8);
73    assert!(core::mem::offset_of!(NiAVObject, fade_amount) == 0x100);
74    assert!(core::mem::offset_of!(NiAVObject, last_updated_frame_counter) == 0x104);
75    assert!(core::mem::offset_of!(NiAVObject, unk104) == 0x108);
76    assert!(core::mem::size_of::<NiAVObject>() == 0x110);
77};
78
79impl NiAVObject {
80    pub const RTTI: VariantID = RTTI_NiObject;
81    pub const NI_RTTI: VariantID = NiRTTI_NiObject;
82    pub const VTABLE: [VariantID; 1] = VTABLE_NiObject;
83
84    #[must_use]
85    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 68835, ae_id = 70187)]
86    pub fn clone(&self) -> *mut NiAVObject {}
87
88    // pub fn cull_geometry(&mut self, cull: bool) {
89    //     todo!()
90    // }
91
92    // pub fn cull_node(&mut self, cull: bool) {
93    //     todo!()
94    // }
95
96    /// Returns whether the object is culled (hidden) in the application.
97    ///
98    /// This function checks the visibility status of the object based on its flags.
99    /// If the object has the [`Flag::Hidden`] set, it is considered culled (i.e., hidden) and will
100    /// not be rendered or processed for certain operations.
101    ///
102    /// The `get_app_culled` function essentially checks if the object is flagged as "hidden" by
103    /// returning a boolean indicating whether the object is culled or not. This is commonly
104    /// used for optimizing rendering performance by excluding objects that should not be visible.
105    ///
106    /// # Returns
107    /// * `true` if the object is culled (i.e., hidden).
108    /// * `false` if the object is not culled (i.e., visible).
109    #[inline]
110    pub fn get_app_culled(&self) -> bool {
111        self.get_flags().is_ok_and(|flag_member| flag_member.contains(Flag::Hidden))
112    }
113
114    #[commonlibsse_ng_derive_internal::relocate_fn(se_id = 25482, ae_id = 26022)]
115    pub fn get_collision_object(&self) -> *mut bhkCollisionObject {}
116
117    // pub fn get_collision_layer(&self) -> COL_LAYER {
118    //     self.collision_object.is_some()
119    // }
120
121    // #[must_use]
122    // pub fn get_first_geometry_of_shader_type(
123    //     &self,
124    //     shader_type: BSShaderMaterialFeature,
125    // ) -> Option<NonNull<BSGeometry>> {
126    //     todo!()
127    // }
128
129    // #[must_use]
130    // pub fn get_mass(&self) -> f32 {
131    //     todo!()
132    // }
133
134    // #[must_use]
135    // pub fn get_user_data(&self) -> Option<NonNull<TESObjectREFR>> {
136    //     todo!()
137    // }
138
139    // pub fn set_user_data(&mut self, ref_obj: Option<NonNull<TESObjectREFR>>) {
140    //     todo!()
141    // }
142
143    // #[must_use]
144    // pub fn has_animation(&self) -> bool {
145    //     todo!()
146    // }
147
148    // #[must_use]
149    // pub fn has_shader_type(&self, shader_type: BSShaderMaterialFeature) -> bool {
150    //     todo!()
151    // }
152
153    // pub fn remove_decals(&mut self) {
154    //     todo!()
155    // }
156
157    // pub fn set_app_culled(&mut self, cull: bool) {
158    //     todo!()
159    // }
160
161    // pub fn set_collision_layer(&mut self, layer: COL_LAYER) {
162    //     todo!()
163    // }
164
165    // pub fn set_collision_layer_and_group(&mut self, layer: COL_LAYER, group: u32) {
166    //     todo!()
167    // }
168
169    // #[must_use]
170    // pub fn set_motion_type(
171    //     &mut self,
172    //     motion_type: hkpMotionType,
173    //     recurse: bool,
174    //     force: bool,
175    //     allow_activate: bool,
176    // ) -> bool {
177    //     todo!()
178    // }
179
180    // #[must_use]
181    // pub fn set_projected_uv_data(
182    //     &mut self,
183    //     uv_params: &NiColorA,
184    //     uv_color: &NiColor,
185    //     is_snow: bool,
186    // ) -> bool {
187    //     todo!()
188    // }
189
190    // pub fn tint_scenegraph(&mut self, color: &NiColorA) {
191    //     todo!()
192    // }
193
194    // pub fn update(&mut self, data: &mut NiUpdateData) {
195    //     todo!()
196    // }
197
198    // pub fn update_body_tint(&mut self, color: &NiColor) {
199    //     todo!()
200    // }
201
202    // pub fn update_hair_color(&mut self, color: &NiColor) {
203    //     todo!()
204    // }
205
206    // pub fn update_material_alpha(&mut self, alpha: f32, do_only_skin: bool) {
207    //     todo!()
208    // }
209
210    // pub fn update_rigid_constraints(&mut self, enable: bool, arg2: u8, arg3: u32) {
211    //     todo!()
212    // }
213
214    // #[must_use]
215    // pub fn get_flags_mut(&mut self) -> &mut stl::Enumeration<Flag, u32> {
216    //     unsafe {
217    //         std::mem::transmute(
218    //             ((self as *mut Self).cast::<u8>().add(0x0F4)) as *mut stl::Enumeration<Flag, u32>,
219    //         )
220    //     }
221    // }
222
223    /// # Errors
224    #[inline]
225    pub fn get_flags(&self) -> Result<&Flag, RelocationError> {
226        relocate_member(self, 0x0F4, 0x10C)
227    }
228
229    /// # Errors
230    #[inline]
231    pub fn get_flags_mut(&mut self) -> Result<&mut Flag, RelocationError> {
232        relocate_member_mut(self, 0x0F4, 0x10C)
233    }
234
235    // pub fn temp_nicast(
236    //     &mut self,
237    //     geometry: &mut BSGeometry,
238    // ) -> Option<NonNull<BSLightingShaderProperty>> {
239    //     todo!()
240    // }
241}
242
243impl crate::re::NiSmartPointer::RefCountable for NiAVObject {
244    #[inline]
245    fn inc_ref_count(&self) {
246        self.__base.__base.__base.inc_ref_count();
247    }
248
249    #[inline]
250    fn dec_ref_count(&mut self) {
251        self.__base.__base.__base.dec_ref_count();
252    }
253}
254
255#[repr(C)]
256pub struct NiAVObjectVtbl {
257    /// C++ class Destructor equivalent
258    pub cxx_drop: unsafe extern "C" fn(this: *mut c_void), // 00
259
260    // override (NiObjectNET)
261    pub GetRTTI: unsafe extern "C" fn(this: *const c_void) -> *const c_void, // 02
262    pub LoadBinary: unsafe extern "C" fn(this: *mut c_void, stream: *mut c_void), // 18
263    pub LinkObject: unsafe extern "C" fn(this: *mut c_void, stream: *mut c_void), // 19
264    pub RegisterStreamables: unsafe extern "C" fn(this: *mut c_void, stream: *mut c_void) -> bool, // 1A
265    pub SaveBinary: unsafe extern "C" fn(this: *mut c_void, stream: *mut c_void), // 1B
266    pub IsEqual: unsafe extern "C" fn(this: *mut c_void, object: *mut c_void) -> bool, // 1C
267    pub ProcessClone: unsafe extern "C" fn(this: *mut c_void, cloning: *mut c_void), // 1D
268
269    // Custom add-ons
270    pub UpdateControllers: unsafe extern "C" fn(this: *mut c_void, data: *mut c_void), // 25
271
272    // VR
273    pub ApplyLocalTransformToWorld: Option<unsafe extern "C" fn(this: *mut c_void)>, // Optional, for VR-specific functionality
274    pub PerformOp: Option<unsafe extern "C" fn(this: *mut c_void, func: *mut c_void)>, // 26
275    pub AttachProperty: Option<unsafe extern "C" fn(this: *mut c_void, property: *mut c_void)>, // 27
276    pub SetMaterialNeedsUpdate: Option<unsafe extern "C" fn(this: *mut c_void, needs_update: bool)>, // 28
277    pub SetDefaultMaterialNeedsUpdateFlag:
278        Option<unsafe extern "C" fn(this: *mut c_void, flag: bool)>, // 29
279    pub GetObjectByName:
280        Option<unsafe extern "C" fn(this: *mut c_void, name: *mut c_void) -> *mut c_void>, // 2A
281    pub SetSelectiveUpdateFlags: Option<
282        unsafe extern "C" fn(
283            this: *mut c_void,
284            a_selective_update: bool,
285            a_selective_update_transforms: bool,
286            a_rigid: bool,
287        ),
288    >, // 2B
289    pub UpdateDownwardPass:
290        Option<unsafe extern "C" fn(this: *mut c_void, data: *mut c_void, arg2: u32)>, // 2C
291    pub UpdateSelectedDownwardPass:
292        Option<unsafe extern "C" fn(this: *mut c_void, data: *mut c_void, arg2: u32)>, // 2D
293    pub UpdateRigidDownwardPass:
294        Option<unsafe extern "C" fn(this: *mut c_void, data: *mut c_void, arg2: u32)>, // 2E
295    pub UpdateWorldBound: Option<unsafe extern "C" fn(this: *mut c_void)>, // 2F
296    pub UpdateWorldData: Option<unsafe extern "C" fn(this: *mut c_void, data: *mut c_void)>, // 30
297    pub UpdateTransformAndBounds:
298        Option<unsafe extern "C" fn(this: *mut c_void, data: *mut c_void)>, // 31
299    pub PreAttachUpdate:
300        Option<unsafe extern "C" fn(this: *mut c_void, parent: *mut c_void, data: *mut c_void)>, // 32
301    pub PostAttachUpdate: Option<unsafe extern "C" fn(this: *mut c_void)>, // 33
302    pub OnVisible: Option<unsafe extern "C" fn(this: *mut c_void, process: *mut c_void)>, // 34
303}
304
305bitflags::bitflags! {
306    /// NiAVObject Flags
307    #[derive(Debug, Clone, Default, PartialEq, Eq, PartialOrd, Ord)]
308    pub struct Flag: u32 {
309        const None = 0;
310        const Hidden = 1 << 0;
311        const SelectiveUpdate = 1 << 1;
312        const SelectiveUpdateTransforms = 1 << 2;
313        const SelectiveUpdateController = 1 << 3;
314        const SelectiveUpdateRigid = 1 << 4;
315        const DisplayObject = 1 << 5;
316        const DisableSorting = 1 << 6;
317        const SelectiveUpdateTransformsOverride = 1 << 7;
318        const SaveExternalGeometryData = 1 << 9;
319        const NoDecals = 1 << 10;
320        const AlwaysDraw = 1 << 11;
321        const MeshLOD = 1 << 12;
322        const FixedBound = 1 << 13;
323        const TopFadeNode = 1 << 14;
324        const IgnoreFade = 1 << 15;
325        const NoAnimSyncX = 1 << 16;
326        const NoAnimSyncY = 1 << 17;
327        const NoAnimSyncZ = 1 << 18;
328        const NoAnimSyncS = 1 << 19;
329        const NoDismember = 1 << 20;
330        const NoDismemberValidity = 1 << 21;
331        const RenderUse = 1 << 22;
332        const MaterialsApplied = 1 << 23;
333        const HighDetail = 1 << 24;
334        const ForceUpdate = 1 << 25;
335        const PreProcessedNode = 1 << 26;
336    }
337}